package root.electronclass.electronclass.other

import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.util.Log
import android.view.LayoutInflater
import android.view.SurfaceHolder
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.annotation.NonNull
import androidx.core.view.isVisible
import androidx.lifecycle.coroutineScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.ToastUtils
import root.electronclass.electronclass.common.base.ViewBindingActivity
import root.electronclass.electronclass.common.util.GridDecoration
import root.electronclass.electronclass.mvp.GlobalParameter
import root.electronclass.electronclass.mvp.base.BaseResponse
import root.electronclass.electronclass.mvp.base.CallbackNext
import root.electronclass.electronclass.mvp.entity.FaceReq
import root.electronclass.electronclass.mvp.rest.RestManager
import root.electronclass.electronclass.R
import root.electronclass.electronclass.databinding.ActivityFaceBinding
import root.electronclass.electronclass.ext.CoroutineExceptionHandler
import root.electronclass.electronclass.setup
import root.electronclass.electronclass.mvp.entity.EcardAttnDTO
import com.hikvision.smarteyes.common.SmartConsts
import com.hikvision.smarteyes.smartdev.FaceSdk
import com.hikvision.smarteyes.smartdev.data.FaceRectAreaView
import com.hikvision.smarteyes.smartdev.data.FaceRectView
import com.hikvision.smarteyes.smartdev.data.SmartDataEvent
import com.hikvision.smarteyes.utils.PicUtils
import com.hikvision.smarteyes.utils.ThreadPoolUtil
import com.hikvision.smarteyes.utils.log.DFLog
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import retrofit2.Call
import java.io.File
import java.util.*


/**
 * 人脸认证
 */
class FaceActivity : ViewBindingActivity<ActivityFaceBinding>(), View.OnClickListener {
    private val TAG = "FaceActivity"
    private var mSurfaceHolderCB: SurfaceHolderCB? = null
    private var mHolder: SurfaceHolder? = null
    private val listInfo = ArrayList<String>()
    private val faceDetectView: FaceRectView? = null
    private val facerectareaview: FaceRectAreaView? = null
    private val showUi = true

    private val isUseTest = false
    private val mContext: Context? = null
    private val isSetLib = false
    private var faceResultAdapter: FaceResultAdapter? = null
    private val listDataList: List<ListData> =
        ArrayList<ListData>()
    private var faceNum = 0
    private var operateRet = 0

    /**
     * 全屏抓拍保存路径
     */
    var path = "/sdcard/fullcap/"

    override fun onStart() {
        super.onStart()
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
            Log.i(TAG, "onStart: register EventBus")
        }
    }

    override fun init() {
        binding.top.setup(lifecycle, "")
        binding.top.title.visibility = View.GONE
        FaceSdk.get().startFaceRecog()

        binding.back.back.setOnClickListener {
            finish()
        }

        binding.btnStart.setOnClickListener(this)

        faceResultAdapter = FaceResultAdapter(binding.recyclerView)
        binding.recyclerView.addItemDecoration(GridDecoration(1, 10, 1, true))
        binding.recyclerView.itemAnimator = DefaultItemAnimator()
        binding.recyclerView.adapter = faceResultAdapter
        mHolder = binding.faceRecognitionSurfaceview.holder
        mSurfaceHolderCB = SurfaceHolderCB(binding)
        mHolder?.addCallback(mSurfaceHolderCB)


        val file = File(path)
        if (!file.exists()) {
            file.mkdir()
        }

    }

    private var isExe = false
    private var recNum = 0
    private fun asyncTask(btn_id: Int) {
        if (isExe) {
            ToastUtils.showShort("模式切换中，请稍后。。")
            return
        }
        isExe = true
        ThreadPoolUtil.getInstance().exe(Runnable {
            recNum = 0
            when (btn_id) {

                R.id.btn_start ->                         //开始识别，使用数据库中的所有数据比对结果。
                    operateRet = FaceSdk.get().startFaceRecog()
            }
            runOnUiThread {
                if (operateRet == 0) {
                    ToastUtils.showShort("操作成功。")
                } else {
                    ToastUtils.showShort("操作失败，错误码 ：$operateRet")
                }
                isExe = false
            }
        })
    }


    override fun onClick(v: View) {
        var ret: Int
        when (v.id) {

            R.id.btn_start ->                 //开始识别，使用数据库中的所有数据比对结果。
                asyncTask(R.id.btn_start)

        }
    }

    /**
     * 显示人脸检测结果
     */
    private fun showFaceDetectResult() {
        val faceLocationDatas = FaceSdk.get().faceLocationDatas
        if (faceLocationDatas == null) {
            DFLog.i(TAG, "faceLocationDatas null")
            return
        }
        for (i in faceLocationDatas.indices) {
            val faceRectFs = faceLocationDatas[i].faceRectFS
            binding.faceRecognitionFacerectview.setFaceRectFs(faceRectFs)
        }
    }

    /*展示抓拍结果*/
    private fun showSnapResult() {
        // TODO: 2019/3/5
        val faceCaptureDatas = FaceSdk.get().faceCaptureDatas
        if (faceCaptureDatas == null || faceCaptureDatas.isEmpty()) {
            return
        }
        val dataList: MutableList<ListData> = ArrayList<ListData>()
        for (faceCaptureData in faceCaptureDatas) {
            val data = ListData()
            data.tv1Value = "抓拍数据"
            data.bitmapCap = faceCaptureData.bmpPic
            dataList.add(data)
        }
        faceResultAdapter?.setData(dataList)
    }

    /**
     * 展示人证对比信息
     */
    private val certNum = 0
    private fun showCertFaceResult() {
        val datas = FaceSdk.get().certFaceResultDatas ?: return
        val listData: MutableList<ListData> =
            ArrayList<ListData>()
        for (i in datas.indices) {
            val certFaceResultData = datas[i]
            val data: ListData =
                ListData()
            data.tv1Value = "人证比对"
            if (certFaceResultData.errCode == 0) {
                val name = certFaceResultData.getmRecord().name.split("_")
                data.tv2Value = """
                姓名：${name[0]},
                类型：${if (name[1] == "1") "学生" else "教师"},
                姓别：${certFaceResultData.getmRecord().sex}
                相似度：${certFaceResultData.sim}
                """.trimIndent()
                data.tv3Value = "证件号码：" + certFaceResultData.getmRecord().cardId
                data.bitmapFace = certFaceResultData.getmRecord().cardBitmap
                data.bitmapCap = certFaceResultData.capBitmap
            } else {
                data.tv2Value = "比对失败，错误码：" + certFaceResultData.errCode
            }
            listData.add(data)
        }
        faceResultAdapter!!.setData(listData)
    }

    /**
     * 展示人脸对比信息
     */
    private fun showRecognitionResult() {
        // TODO: 2019/1/28
        val datas = FaceSdk.get().identifyResultDatas ?: return
        faceNum++
        val listData: MutableList<ListData> =
            ArrayList<ListData>()
        for (i in datas.indices) {
            val faceIdentifyData = datas[i]

            val data: ListData =
                ListData()
            data.tv1Value = "识别数据"
            if (faceIdentifyData.sim < 0) {
                data.tv2Value = "陌生人"
                data.tv3Value = """
                人脸序号：${faceIdentifyData.faceSeq}
                温度：${faceIdentifyData.faceTemperature}
                """.trimIndent()
            } else {
                val name = faceIdentifyData.faceId.split("_")
                data.tv2Value = "在库人员 " + faceIdentifyData.sim
                data.tv3Value = """
                ID：${name[0]}
                类型：${if (name[1] == "1") "学生" else "教师"}
                温度：${faceIdentifyData.faceTemperature}
                """.trimIndent()
                data.bitmapFace = FaceSdk.get().getFacePic(faceIdentifyData.faceId)
            }
            data.bitmapCap = faceIdentifyData.capBitmap
            listData.add(data)
            getData(datas[0].faceId)
        }
        faceResultAdapter?.setData(listData)

    }


    private fun showCertInfoResult() {
        val datas = FaceSdk.get().idCardInfo ?: return
        val dataList: MutableList<ListData> =
            ArrayList<ListData>()
        for (i in datas.indices) {
            val record = datas[i]
            val data: ListData =
                ListData()
            data.tv1Value = "证件数据"
            val name = record.name.split("_")
            data.tv2Value = """
            姓名：${name[0]},
            类型：${if (name[1] == "1") "学生" else "教师"},
            姓别：${record.sex}
            """.trimIndent()
            data.tv3Value = "证件号码：" + record.cardId
            data.bitmapFace = record.cardBitmap
            dataList.add(data)
        }
        faceResultAdapter!!.setData(dataList)
    }


    private fun getData(name: String){
        val n = name.split("_")
        RestManager.getInstance().initRest().face(FaceReq(n[0],n[1].toInt()))
            .enqueue(object : CallbackNext<BaseResponse<String>>(mDialogViewModel) {
                override fun onSuccessful(call: Call<BaseResponse<String>>?, response: BaseResponse<String>) {
                    if (response.isSuccess) {
                        GlobalParameter.setEventType(2)
                        GlobalParameter.setCardNum(null)
                        RestManager.getInstance().token = response.rows
                        RestManager.getInstance().initService()
                        //考勤打卡
                        if (intent.getIntExtra("RequestCode", 0) == AttestationActivity.ATTENDANCE) {
                            RestManager.getInstance().initRest().saveAttn(EcardAttnDTO()).enqueue(object : CallbackNext<BaseResponse<Any>>(mDialogViewModel) {
                                override  fun onSuccessful(call: Call<BaseResponse<Any>>?, response: BaseResponse<Any>?) {
                                    Log.i("CardActivity", "onSuccessful: ${response}")
                                    binding.resultCl.isVisible = true
                                    if (response?.code == 200){
                                        binding.resultTv.text = "打卡成功"
                                        binding.result.setImageResource(R.mipmap.success_icon)
                                        binding.resultTv1.text = "恭喜你，已完成考勤打卡"
                                    }else{
                                        binding.resultTv.text = "打卡失败"
                                        binding.result.setImageResource(R.mipmap.fault_icon)
                                        binding.resultTv1.text = response?.msg
                                    }
                                    lifecycle.coroutineScope.launch(CoroutineExceptionHandler()) {
                                        delay(3000)
                                        setResult(Activity.RESULT_OK)
                                        finish()
                                    }
                                }

                                override fun onError(call: Call<BaseResponse<Any>>?, response: BaseResponse<Any>?) {
                                    binding.resultTv.text = "打卡失败"
                                    binding.result.setImageResource(R.mipmap.fault_icon)
                                    binding.resultTv1.text = response?.msg
                                    lifecycle.coroutineScope.launch(CoroutineExceptionHandler()) {
                                        delay(3000)
                                        setResult(Activity.RESULT_OK)
                                        finish()
                                    }
                                }

                            })
                        } else {
                            toast("登录成功")
                            setResult(Activity.RESULT_OK)
                            finish()
                        }
                    }
                }

                override fun onError(call: Call<BaseResponse<String>>?, response: BaseResponse<String>?) {
                    toast(response?.msg)
                }

            })
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onSmartDataEvent(messageEvent: SmartDataEvent) {
        when (messageEvent.dataType) {
            SmartConsts.DEV_SMARTDATA_CAPTURE -> showSnapResult()
            SmartConsts.DEV_SMARTDATA_IDENTIFY -> if (showUi) {
                showRecognitionResult()
            } else {
                ToastUtils.showShort("不再展示识别结果")
            }
            SmartConsts.DEV_SMARTDATA_LOCATION -> showFaceDetectResult()
            SmartConsts.DEV_SMARTDATA_CERTFACE -> showCertFaceResult()
            SmartConsts.DEV_SMARTDATA_IDCARDINFO -> showCertInfoResult()
            SmartConsts.DEV_SMARTDATA_FULL_CAPTURE -> {
                val fullCaptureDatas = FaceSdk.get().fullCaptureDatas
                if (fullCaptureDatas != null && fullCaptureDatas.size > 0) {
                    Log.i(
                        TAG,
                        "full capture,fullCaptureData = " + fullCaptureDatas[0]
                    )
                    ToastUtils.showShort("抓全图成功！文件查看路径：/sdcard/fullcap/")
                    ThreadPoolUtil.getInstance().exe {
                        val current = System.currentTimeMillis()
                        PicUtils.saveBitmap2Jpg(
                            PicUtils.getBmpByBytes(fullCaptureDatas[0].jpgData),
                            "$path$current.jpg"
                        )
                    }
                }
            }
            else -> {}
        }
    }


    class SurfaceHolderCB(binding: ActivityFaceBinding) : SurfaceHolder.Callback {
        val bind = binding
        override fun surfaceCreated(holder: SurfaceHolder) {
            val ret: Int = FaceSdk.get().startPreview(bind.faceRecognitionSurfaceview)
            if (ret != 0) {
                ToastUtils.showShort("播放错误，err = $ret")
            }
        }

        override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
            //Log.e(MainActivity.TAG,"surfaceChanged");
        }

        override fun surfaceDestroyed(holder: SurfaceHolder) {
            FaceSdk.get().stopPreview()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        /**
         * 退出界面时再停止任务
         */
        /**
         * 退出界面时再停止任务
         */
        FaceSdk.get().stopFaceTask()
        EventBus.getDefault().unregister(this)
    }

    internal class FaceResultAdapter(val recyclerView: RecyclerView) : RecyclerView.Adapter<ViewHolder>() {
        //        private List<ListData> data = new ArrayList<>();
        private val data: LinkedList<ListData>? =
            LinkedList<ListData>()

        private fun addData(d: ListData) {
            if (data!!.size >= 10) {
                data.removeAt(9)
                notifyItemRemoved(9)
            }
            data.add(0, d)
            this.notifyItemInserted(0)
            if (recyclerView.scrollState === RecyclerView.SCROLL_STATE_IDLE) {
                recyclerView.scrollToPosition(0)
            }
        }

        fun setData(d: List<ListData>) {
            Log.i("FaceActivity", "setData: ${d.toString()}")
            //数据过多时及时清除
            if (data!!.size > 6) {
                data.clear()
            }

            //添加新数据，后识别的排在最前面
            for (i in d.indices.reversed()) {
                data.addFirst(d[i])
            }
            notifyDataSetChanged()

        }

        @NonNull
        override fun onCreateViewHolder(@NonNull parent: ViewGroup, viewType: Int): ViewHolder {
            val view: View =
                LayoutInflater.from(parent.context).inflate(R.layout.item_face_identity_result, parent, false)
            //            ViewHolder viewHolder = new ViewHolder(view);
            return ViewHolder(view)
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            Log.i("FaceActivity", "onBindViewHolder: enter.");
            val bean: ListData = data!![position]
            if (bean.tv1Value != null) {
                holder.tv_1_1.setText(bean.tv1Value)
            } else {
                holder.tv_1_1.text = ""
            }
            if (bean.tv2Value != null) {
                holder.tv_1_2.setText(bean.tv2Value)
            } else {
                holder.tv_1_2.text = ""
            }
            if (bean.tv3Value != null) {
                holder.tv_1_3.setText(bean.tv3Value)
            } else {
                holder.tv_1_3.text = ""
            }
            if (bean.bitmapCap != null) {
                holder.imgCapPhoto.setImageBitmap(bean.bitmapCap)
            } else {
                holder.imgCapPhoto.setImageBitmap(null)
            }
            if (bean.bitmapFace != null) {
                holder.imgFacePhoto.setImageBitmap(bean.bitmapFace)
            } else {
                holder.imgFacePhoto.setImageBitmap(null)
            }
        }


        override fun getItemCount(): Int {
            return data?.size ?: 0
        }
    }


    internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var imgCapPhoto: ImageView
        var imgFacePhoto: ImageView
        var tv_1_1: TextView
        var tv_1_2: TextView
        var tv_1_3: TextView

        init {
            imgCapPhoto = itemView.findViewById(R.id.img_item_face_cap_photo)
            imgFacePhoto = itemView.findViewById(R.id.img_item_face_cert_photo)
            tv_1_1 = itemView.findViewById(R.id.tv_item_1_1)
            tv_1_2 = itemView.findViewById(R.id.tv_item_1_2)
            tv_1_3 = itemView.findViewById(R.id.tv_item_1_3)
        }
    }


    internal class ListData {
        var tv1Value: String? = null
        var tv2Value: String? = null
        var tv3Value: String? = null
        var bitmapCap: Bitmap? = null
        var bitmapFace: Bitmap? = null
    }


}